import * as fs from 'node:fs'
import * as path from 'node:path'

export function makeAbility(folderPath: string) {
    try {
        const entryPath = path.join(folderPath, 'entry', 'src', 'main', 'ets', 'entryability')
        const oldEntryPath = path.join(folderPath, 'entry', 'src', 'main', 'ets', 'entryability', 'EntryAbilityOld.ets')
        const runnerPath = path.join(folderPath, 'entry', 'src', 'main', 'ets', 'TestRunner', 'OpenHarmonyTestRunner.ts')
        const runnerStr = fs.readFileSync(runnerPath, { encoding: 'utf8', flag: 'r' })
        const abilities = runnerStr.match(/\.MainAbility|\.TestAbility|\.EntryAbility/g)
        if (abilities && abilities.length > 0) {
            let removePaths: string[] = []
            switch (abilities[0]) {
                case '.MainAbility':
                    copyEntryAbility(entryPath)
                    moveOldAbility(path.join(folderPath, 'entry', 'src', 'main', 'ets', 'MainAbility', 'MainAbility.ts'), oldEntryPath)
                    removePaths = [path.join(folderPath, 'entry', 'src', 'main', 'ets', 'TestAbility')]
                    break
               case '.TestAbility':
                    copyEntryAbility(entryPath)
                    moveOldAbility(path.join(folderPath, 'entry', 'src', 'main', 'ets', 'TestAbility', 'TestAbility.ets'), oldEntryPath)
                    break
               case '.EntryAbility':
                    removePaths = [path.join(folderPath, 'entry', 'src', 'main', 'ets', 'TestAbility')]
                    break
                default:
                    throw new Error('Unexpected ability: ' + abilities[0])
            }
            const runnerConflict = abilities.some(value => value !== abilities[0])
            if (runnerConflict) {
                console.warn('\x1b[33m%s\x1b[0m', 'WARNING Check ability in OpenHarmonyTestRunner.ts. Check and remove old folders manually (TestAbility, TestRunner).')
            } else {
                removePaths.push(path.join(folderPath, 'entry', 'src', 'main', 'ets', 'TestRunner'))
            }
            removePaths.forEach(p => {
                fs.rmSync(p, { recursive: true, force: true })
                console.info('Removed ' + p)
            })
            console.info(`EntryAbility has been prepared.`)
            console.info('\x1b[33m%s\x1b[0m', `Please synchronize EntryAbility with EntryAbilityOld and remove EntryAbilityOld.ets`)
        } else {
            copyEntryAbility(entryPath)
            throw new Error('An ability is not found.')
        }
    } catch (err) {
        console.error('Error: ' + err)
        console.warn('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
        console.warn('\x1b[33m%s\x1b[0m', 'WARNING EntryAbility is not created. Please check EntryAbility manually.')
        console.warn('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
    }
}

function copyEntryAbility(dstEntryPath: string) {
    const srcEntryPath = path.join(__dirname, '..', '..', '..', 'template3', 'entryability')
    fs.cpSync(srcEntryPath, dstEntryPath, {recursive: true})
}

function moveOldAbility(srcAbilityPath: string, dstAbilityPath: string) {
    fs.copyFile(srcAbilityPath, dstAbilityPath, err => {
        if (err) {
            console.error('\x1b[31m%s\x1b[0m', `EntryAbilityOld is not copied. Error: ${err}.`)
        }
        fs.unlinkSync(srcAbilityPath)
    })
}
